//
//  UIImageView+Progress.m
//  MMBangADDemoProject
//
//  Created by CuiPanJun on 14-9-24.
//  Copyright (c) 2014年 CuiPanJun. All rights reserved.
//

#import "UIImageView+Progress.h"
#import "UIImageView+WebCache.h"
#import "LProgressView.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "MMBProgressView.h"

#define IMAGE_MASK_VIEW_TAG 1001
#define FAILED_TO_DOWNLOAD_IMGVIEW 1002

static char progressViewKey;
static char indicatorViewKey;

@implementation UIImageView (Progress)

- (void)mmb_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
    [self setImageWithURL:url placeholderImage:placeholder completeblock:^(UIImage *image, NSError *error, SDImageCacheType cacheType,NSURL *url) {
        //remove memory cache for gifs
        if (image.images) {
            [[SDImageCache sharedImageCache] removeImageForKey:[url absoluteString] fromDisk:NO];
        }
    } showProgress:NO];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder showProgress:(BOOL)show {
    [self setImageWithURL:url placeholderImage:placeholder completeblock:nil showProgress:show andProgressStyle:ProgressStyle_Defaut];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder showProgress:(BOOL)show andProgressStyle:(ProgressStyle)progressStyle
{
    if (!progressStyle) {
        progressStyle = ProgressStyle_Defaut;
    }
    [self setImageWithURL:url placeholderImage:placeholder completeblock:nil showProgress:show andProgressStyle:progressStyle];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completeblock:(SDWebImageCompletionBlock)outBlock showProgress:(BOOL)show
{
    [self setImageWithURL:url placeholderImage:placeholder completeblock:outBlock showProgress:show showFailView:YES andProgressStyle:ProgressStyle_Defaut];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completeblock:(SDWebImageCompletionBlock)outBlock showProgress:(BOOL)show andProgressStyle:(ProgressStyle)progressStyle
{
        [self setImageWithURL:url placeholderImage:placeholder completeblock:outBlock showProgress:show showFailView:YES andProgressStyle:progressStyle];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completeblock:(SDWebImageCompletionBlock)outBlock showProgress:(BOOL)show showFailView:(BOOL)showFail
{
    [self setImageWithURL:url placeholderImage:placeholder completeblock:outBlock showProgress:show showFailView:YES andProgressStyle:ProgressStyle_Defaut];
}

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completeblock:(SDWebImageCompletionBlock)outBlock showProgress:(BOOL)show showFailView:(BOOL)showFail andProgressStyle:(ProgressStyle)progressStyle {
    if (!url) {
        self.image = placeholder;
        if (outBlock) {
            outBlock(nil,nil,SDImageCacheTypeNone,url);
        }
    }
    //clean up if needed
    UIView *failedToDownloadImageView = [self viewWithTag:FAILED_TO_DOWNLOAD_IMGVIEW];
    [failedToDownloadImageView removeFromSuperview];
    UIView<UIProgressDelegate> *progressView = [self progressView];
    if ([progressView respondsToSelector:@selector(clean)]) {
        [progressView performSelector:@selector(clean) withObject:nil];
    }
    SDWebImageDownloaderProgressBlock progressBlock;
    SDWebImageCompletionBlock completeBlock;
    if (!progressStyle) {
        progressStyle = ProgressStyle_Defaut;
    }
    if (show) {
        id progressView = nil;
        switch (progressStyle) {
            case ProgressStyle_Defaut:
            {
                static dispatch_once_t onceToken;
                dispatch_once(&onceToken, ^{
                    [[LProgressAppearance sharedProgressAppearance] setType:LProgressTypeAnnular];
                    [[LProgressAppearance sharedProgressAppearance] setSchemeColor:[UIColor colorWithHex:0x4bc8f5 alpha:1]];
                    [[LProgressAppearance sharedProgressAppearance] setPercentageTextColor:    [UIColor colorWithHex:0x4bc8f5 alpha:1]];
                });
                LProgressView *progressV = [[LProgressView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
                progressV.progressAppearance = [LProgressAppearance sharedProgressAppearance];
                progressView = progressV;
            }
                break;
            case ProgressStyle_MMBProgress:
            {
                MMBProgressView *temProgressView = [[MMBProgressView alloc] initWithFrame:CGRectMake(self.width*1./3., 0, self.width*2./3., 7) style:MMBProgressViewStyleRoundDoubleBorder];
                [temProgressView setProgressImage:[TKUtil createImageFromColor:[UIColor colorWithHex:kMainColor alpha:1.]] isPattern:YES];
                [temProgressView setTrackImage:[TKUtil createImageFromColor:[UIColor clearColor]]];
                progressView = temProgressView;
            }
                break;
                
            default:
                break;
        }
        [self setupWithProgressView:(UIView<UIProgressDelegate> *)progressView];
        [self performSelector:@selector(showProgressDelay) withObject:nil afterDelay:0.1];
        kWeakSelf
        progressBlock = ^(NSInteger recievedSize, NSInteger exceptedSize){
            if (recievedSize <= 0 ) {
                recievedSize = 0;
            }
            if (exceptedSize <= 0) {
                exceptedSize = 1;
            }
            float progress = recievedSize * 1.0 / exceptedSize;
            [weakSelf setProgress:progress];
        };
        completeBlock = ^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
            [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(showProgressDelay) object:nil];
            //remove maskview after 1s delay
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                UIView *maskView = [weakSelf viewWithTag:IMAGE_MASK_VIEW_TAG];
                [maskView removeFromSuperview];
                if (outBlock) {
                    outBlock(image, error,cacheType,url);
                }
                if (error) {
                    NSLog(@"fail to get image");
                    [weakSelf showProgress:NO];
                    [weakSelf setProgress:1];
                    if (showFail) {
                        UIView *failureView = [[self class] createFailureView:weakSelf.bounds];
                        [weakSelf addSubview:failureView];
                    }
                }
            });
        };

    }else {
        completeBlock = outBlock;
    }
//    [self setImageWithURL:url
//         placeholderImage:placeholder
//                  options:SDWebImageRetryFailed
//                 progress:progressBlock
//                completed:completeBlock];
//    
    
    [self sd_setImageWithURL:url placeholderImage:placeholder options:SDWebImageRetryFailed progress:progressBlock completed:completeBlock];
    
}

- (void)didMoveToWindow {
    if (!self.window) {
        UIView<UIProgressDelegate> *progressView = [self progressView];
        [progressView setProgress:1];
    }
}

+ (UIView *)createFailureView:(CGRect)frame {
    UIView *backgroundView = [[UIView alloc] initWithFrame:frame];
    backgroundView.backgroundColor = [UIColor colorWithHex:0xf4f4f4 alpha:1];
    backgroundView.tag = FAILED_TO_DOWNLOAD_IMGVIEW;
    UIImage *image = [TKUtil createDefaultImage:@"failToLoad" InView:backgroundView];
    UIImageView *failureView = [[UIImageView alloc] initWithImage:image];
    failureView.center = backgroundView.myCenter;
    [backgroundView addSubview:failureView];
    return backgroundView;
}

- (UIView<UIProgressDelegate> *)progressView{
    return objc_getAssociatedObject(self, &progressViewKey);
}

- (void)setProgressView:(UIView<UIProgressDelegate> *)progressView{
    objc_setAssociatedObject(self, &progressViewKey, progressView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIView *)indicatorView{
    return objc_getAssociatedObject(self, &indicatorViewKey);
}

- (void)setIndicatorView:(UIView *)indicatorView{
    objc_setAssociatedObject(self, &indicatorViewKey, indicatorView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)setupWithActivityIndicator:(UIView *)indicatorView{
    UIView *maskView = [self viewWithTag:IMAGE_MASK_VIEW_TAG];
    if (!maskView) {
        maskView = [[UIView alloc] initWithFrame:self.bounds];
        maskView.tag = IMAGE_MASK_VIEW_TAG;
        maskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self addSubview:maskView];
    }
    maskView.hidden = YES;
    [self setIndicatorView:indicatorView];
    indicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
    indicatorView.center = maskView.center;
    //indicatorView.hidden = YES;
    [maskView addSubview:indicatorView];
}

- (void)setupWithProgressView:(UIView<UIProgressDelegate> *)progressView{
    UIView *maskView = [self viewWithTag:IMAGE_MASK_VIEW_TAG];
    if (!maskView) {
        maskView = [[UIView alloc] initWithFrame:self.bounds];
        maskView.tag = IMAGE_MASK_VIEW_TAG;
        maskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self addSubview:maskView];
    }
    maskView.hidden = YES;

    [self setProgressView:progressView];
    progressView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
    progressView.center = maskView.center;
    progressView.hidden = NO;
    [maskView addSubview:progressView];
}

- (void)showProgress:(BOOL)show {
    UIView *maskView = [self viewWithTag:IMAGE_MASK_VIEW_TAG];
    
    if (show) {
        maskView.hidden = NO;
        [self progressView].hidden = NO;
        [self indicatorView].hidden = YES;
    } else {
        maskView.hidden = YES;
        [self progressView].hidden = YES;
    }
}

- (void)setProgress:(float)_progress{
   
    __block float progress= _progress;

//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        UIView<UIProgressDelegate> *progressView = [self progressView];
//        if (_progress <= 0) {
//            [self showProgress:YES];
//        }
        if (progress >= 1) {
            progress = 1;
        }

        if ([progressView respondsToSelector:@selector(setProgress:)]) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                [progressView  setProgress:progress];
            });
            
        }
//    });
}

- (void)startActivityAnimation{
    UIView *maskView = [self viewWithTag:IMAGE_MASK_VIEW_TAG];
    if (!maskView) {
        maskView = [[UIView alloc] initWithFrame:self.bounds];
        maskView.tag = IMAGE_MASK_VIEW_TAG;
        maskView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self addSubview:maskView];
    }
    maskView.hidden = NO;
    
    UIView *indicatorV = [self indicatorView];
    if ([indicatorV respondsToSelector:@selector(startAnimating)]) {
        [[self indicatorView] performSelector:@selector(startAnimating)];
    }
    
}

- (void)stopActivityAnimating{
    UIView *maskView = [self viewWithTag:IMAGE_MASK_VIEW_TAG];
    maskView.hidden = YES;
    
    UIView *indicatorV = [self indicatorView];
    indicatorV.hidden = YES;
    if ([indicatorV respondsToSelector:@selector(stopAnimating)]) {
        [[self indicatorView] performSelector:@selector(stopAnimating)];
    }
    
}

- (void)showProgressDelay{
    [self showProgress:YES];
}

- (void)hideProgressDelay{
    [self showProgress:NO];
}

@end
